package com.mapfinal.server;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.google.common.collect.Lists;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.DbPro;
import com.lambkit.Lambkit;
import com.lambkit.core.aop.AopKit;
import com.mapfinal.resource.postgis.PostgisServerDataStore;
import com.mapfinal.resource.shapefile.ShapefileServerDataStore;
import com.mapfinal.server.layer.ServerDataStore;
import com.mapfinal.server.layer.ServerLayer;
import com.mapfinal.server.layer.model.MfDatastore;
import com.mapfinal.server.layer.model.MfLayer;
import com.mapfinal.server.layer.model.MfWorkspace;

public class MapfinalServer {
    
	/**
	 * wms的format转图片格式
	 */
	private static Map<String, String> mapMimeType = new HashMap<>();
	
	/**
	 * MapfinalServer
	 */
	private static MapfinalServer server = null;
    
	/**
	 * MapfinalServer所管理的数据库句柄
	 * @return
	 */
	public static DbPro db() {
		MapfinalServerConfig config = Lambkit.config(MapfinalServerConfig.class);
        String dbconfig = config.getDbConfig();
        if(StrKit.notBlank(dbconfig)) {
            return Db.use(dbconfig);
        } else {
            return Db.use();
        }
    }
	
	/**
	 *  图层列表
	 */
	private Map<String, ServerLayer> layers;
	/**
	 * 存储列表
	 */
	private Map<Integer, ServerDataStore> dataStores;
	/**
	 * 默认的工作空间
	 */
	private MfWorkspace defaultWorkspace;
	
	public MapfinalServer() {
		layers = new ConcurrentHashMap<String, ServerLayer>();
		dataStores = new ConcurrentHashMap<Integer, ServerDataStore>();
	}
	
	public static MapfinalServer me() {
		if(server==null) {
			server = AopKit.singleton(MapfinalServer.class);
		}
		return server;
	}
	
	public MfLayer getMfLayer(String name) {
		return  MfLayer.service().getLayer(name);
	}
	
	public List<MfLayer> getMfLayers(String names) {
		return  MfLayer.service().getLayerList(names);
	}
	
	/**
	 * 获取图层
	 * @param name
	 * @return
	 */
	public ServerLayer getLayer(String name) {
		ServerLayer layer = layers.get(name);
		if(layer==null) {
			MfLayer mfLayer = MfLayer.service().getLayer(name);
			if(mfLayer==null) return null;
			System.out.println("MfLayer: " + mfLayer.getName() + ", id=" + mfLayer.getId());
			layer = createLayer(mfLayer);
			addLayer(name, layer);
		}
		return layer;
	}
	
	/**
	 * 获取图层列表
	 * @param names
	 * @return
	 */
	public List<ServerLayer> getLayers(String names) {
		List<ServerLayer> layers = Lists.newArrayList();
		String[] nameArray = names.split(",");
		if(nameArray.length > 0) {
			for(int i=0; i<nameArray.length; i++) {
				System.out.println("layerName: "+ nameArray[i]);
				ServerLayer layer = getLayer(nameArray[i]);
				if(layer!=null) layers.add(layer);
			}
		}
		return layers;
	}
	
	/**
	 * 创建ServerLayer
	 * @param mfLayer
	 * @return
	 */
	public ServerLayer createLayer(MfLayer mfLayer) {
		// TODO Auto-generated method stub
		if(mfLayer==null) return null;
		ServerLayer serverLayer = layers.get(mfLayer.getName());
		if(serverLayer!=null) return serverLayer;
		ServerDataStore dataStore = createDataStore(mfLayer);
		if(dataStore!=null) {
			serverLayer = dataStore.getServerLayer(mfLayer.getName());
			layers.put(mfLayer.getName(), serverLayer);
		}
		return serverLayer;
	}
	
	/**
	 * 创建并保存ServerDataStore
	 * @param mfDatastore
	 * @return
	 */
	public ServerDataStore createDataStore(MfLayer mfLayer) {
		if(mfLayer==null) return null;
		Integer storeid = mfLayer.getStoreid();
		if(storeid==null) return null;
		ServerDataStore dataStore = dataStores.get(storeid);
		if(dataStore==null) {
			MfDatastore mfDatastore = MfDatastore.service().findById(storeid);
			if(mfDatastore==null) return null;
			dataStore = createDataStore(mfDatastore);
		}
		return dataStore;
	}
	
	/**
	 * 创建并保存ServerDataStore
	 * @param mfDatastore
	 * @return
	 */
	public ServerDataStore createDataStore(MfDatastore mfDatastore) {
		if(mfDatastore==null) return null;
		ServerDataStore serverDataStore = dataStores.get(mfDatastore.getId());
		if(serverDataStore!=null) return serverDataStore;
		Integer type = mfDatastore.getType();
		switch (type) {
		case MapfinalServerConsts.DATASTORE_SHP:
			serverDataStore = new ShapefileServerDataStore(mfDatastore);
			serverDataStore.start();
			break;
		case MapfinalServerConsts.DATASTORE_POSTGIS:
			serverDataStore = new PostgisServerDataStore(mfDatastore);
			serverDataStore.start();
			break;
		}
		if(serverDataStore!=null) {
			dataStores.put(mfDatastore.getId(), serverDataStore);
		}
		return serverDataStore;
	}
	
	/**
	 * 关闭并移除serverDataStore
	 * @param storeid
	 */
	public void removeDataStore(Integer storeid) {
		ServerDataStore serverDataStore = dataStores.remove(storeid);
		if(serverDataStore!=null) {
			serverDataStore.stop();
		}
		serverDataStore = null;
	}

	/**
	 * 添加图层
	 * @param name
	 * @param layer
	 */
	public void addLayer(String name, ServerLayer layer) {
		layers.put(name, layer);
	}
	
	public Map<String, ServerLayer> getLayers() {
		return layers;
	}

	public Map<Integer, ServerDataStore> getDataStores() {
		return dataStores;
	}

	public void setDataStores(Map<Integer, ServerDataStore> dataStores) {
		this.dataStores = dataStores;
	}
	
	
	public static String imageFormat(String format) {
		return mapMimeType.get(format);
	}
	
	/**
	 * 获取默认的工作空间
	 * @return
	 */
	public MfWorkspace getDefaultWorkspace() {
		if(defaultWorkspace==null) {
			defaultWorkspace = MfWorkspace.service().getDefault();
		}
		return defaultWorkspace;
	}

	public void setDefaultWorkspace(MfWorkspace defaultWorkspace) {
		// 首先确认数据库中的默认替换是否成功
		if(MfWorkspace.service().changeDefault(defaultWorkspace)) {
			this.defaultWorkspace = defaultWorkspace;
		}
	}

	static {
		mapMimeType.put("image/png", "png");
		mapMimeType.put("image/bmp", "bmp");
		mapMimeType.put("image/jpeg", "jpg");
		mapMimeType.put("image/tiff", "tiff");
		mapMimeType.put("image/gif", "gif");
		mapMimeType.put("image/svg+xml", "svg");
		mapMimeType.put("image/svg-xml", "svg");
	}
}
